home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-01-20 | 55.0 KB | 2,073 lines |
- Newsgroups: comp.sources.misc
- From: tony@ajfcal.cuc.ab.ca (Tony Field)
- Subject: v27i100: psf3 - Postscript print filter system, v3, Part09/09
- Message-ID: <1992Jan21.013608.11883@sparky.imd.sterling.com>
- X-Md4-Signature: 26baf202402123037516542481bcd20b
- Date: Tue, 21 Jan 1992 01:36:08 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: tony@ajfcal.cuc.ab.ca (Tony Field)
- Posting-number: Volume 27, Issue 100
- Archive-name: psf3/part09
- Environment: ISC, SUNOS, SYSVR3, DOS
- Supersedes: psf2: Volume 12, Issue 4-9
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 9 (of 9)."
- # Contents: psf.c
- # Wrapped by ajf@trifid on Sat Jan 18 22:55:51 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'psf.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'psf.c'\"
- else
- echo shar: Extracting \"'psf.c'\" \(52453 characters\)
- sed "s/^X//" >'psf.c' <<'END_OF_FILE'
- X/* ta=4 set tabstop=4 */
- X/****************************************************************************
- X* p s f . c v3 *
- X* *
- X* Print text files to postscript printer. *
- X* *
- X* Tony Field: tony@ajfcal.cuc.ab.ca *
- X****************************************************************************/
- X/*
- X * $Id: psf.c,v 3.2 1992/01/19 05:50:33 ajf Exp ajf $
- X*/
- X/* Three versions of psf can be compiled:
- X
- X psf: postscript filter for command line use.
- X
- X psffilter: used with lp/lpsched. accepts command line argument.
- X Input on stdin. compile with -DPSFFILTER.
- X
- X psflpd: used with lpr/lpd. does not accept command line
- X arguments. compile with -DPSFFILTER -DFORLPD
- X */
- X
- X#include <stdio.h>
- X#include <malloc.h>
- X#include <string.h>
- X#include <setjmp.h>
- X#include <math.h>
- X#include <time.h>
- X#include <signal.h>
- X#include "ctp.h"
- X#include "patchlevel.h"
- X#include "psf.h"
- X#include "psfproto.h"
- X
- X#if defined(MSDOS) || defined (__MSDOS__)
- X#ifndef BINDIR
- X#define BINDIR "c:/bin"
- X#endif
- X#ifndef PDEF
- X#define PDEF "c:/lib/psfprint.def"
- X#endif
- X#endif
- X
- X#ifndef PAPERTYPE
- X#define PAPERTYPE "letter"
- X#endif
- X#ifndef PSFDOUB
- X#define PSFDOUB "psfdoub"
- X#endif
- X
- X/* set up the mechanism for underline display */
- X
- X#define SHOWU(fp,ps) fprintf (fp, ") %d showuline\n", ps)
- X
- X#define NOMINAL_CWIDE 7.2001 /* point width for Courier 12-point */
- X#define NOMINAL_POINTS 12 /* standard 12-point for printing */
- X
- X#define NORMAL 0x00 /* bitset for print_attributes */
- X#define ITALICS 0x01
- X#define BOLD 0x02
- X#define UNDERLINE 0x04 /* must be 0x04. underline is not a font */
- X
- X#define CTLD_EOJ 0x04 /* ctl/d is end of postscript job. */
- X
- X/* Paper physical dimensions.
- X The default paper sizes is for a NEC LC890 and is overridden in
- X "psfprint.def".
- X*/
- X
- Xtypedef struct /* measurement in point */
- X{ char paper_name[60]; /* name of paper size (for command line) */
- X char paper_tray[100]; /* postscript operator to select this tray */
- X int width; /* portrait point width of paper */
- X int height; /* portrait point height of paper */
- X int lx, ly, ux, uy;
- X int left_marg; /* margin widths (unprintable area) */
- X int bot_marg; /* " */
- X int right_marg; /* " */
- X int top_marg; /* " */
- X int x_size; /* generated by psf. */
- X int y_size; /* size after correction for line count */
- X} measure;
- X
- Xmeasure *p; /* working set of parameters (points to something below) */
- Xmeasure page_types[NPAGE] =
- X{ { "letter",
- X "statusdict begin lettertray end",
- X 612, 792, 18, 15, 593, 777
- X },
- X { "legal",
- X "statusdict begin legaltray end",
- X 612, 1008, 18, 15, 593, 993
- X },
- X { "a4",
- X "statusdict begin a4tray end",
- X 595, 842, 18, 15, 578, 827
- X },
- X { "b5",
- X "statusdict begin b5tray end",
- X 516, 729, 18, 15, 497, 712
- X },
- X { "", /* end of paper list */
- X "",
- X 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- X }
- X};
- X
- Xchar order_default[20] = "Normal";
- Xchar order_normal[100] = "\0";
- Xchar order_reverse[100] = "\0";
- Xchar *order_command = NULL;
- X
- Xchar slots[NSLOTS][200] =
- X{ "statusdict begin 1 setpapertray end",
- X "statusdict begin 2 setpapertray end",
- X "", "", "", ""
- X} ;
- Xint nslots = 2;
- X
- Xint y_top_offset; /* offsets for each frame */
- Xint x_left_offset;
- Xint dx_home[4]; /* page frame home (0,0) translations */
- Xint dy_home[4];
- X
- Xint x,y; /* current x,y coordinate */
- Xdouble scale_x, scale_y; /* scale factors for 2-up, 4-up printing */
- Xint real_width;
- X
- Xlong *pg_loc; /* double side print byte ptr to %%Page: */
- Xint npg_loc; /* number of elements in pg_loc[] */
- X
- Xint book = 0; /* book format: double sided */
- Xint bookwork = 0; /* book format, 2-up print */
- Xint lines_on_page = 60; /* user print lines on page */
- Xint lines_total = 0; /* total number of lines for scale purposes */
- Xint chars_on_line = 80; /* default number of chars on line */
- Xint landscape = 0; /* 1 = landscape, 0 = portrait layout */
- Xint header = 0; /* 1 = print header at top of each page */
- Xint cross = 0; /* 1 = print cross on 4-up pages */
- Xint line_number = 0; /* current logical line number on page */
- Xint tab_size = 8; /* space translation for tabs. */
- Xint font_number = 0; /* one of the valid fonts in the printer */
- Xint point_size = 12; /* can be changed with the -p option */
- Xint x_user_offset = 0; /* offsets specified buy user */
- Xint y_user_offset = 0; /* points from physical page edge. */
- Xint set_paper_tray = 0; /* user has set paper tray selection */
- Xint set_line_count = 0; /* print line count on page */
- Xint set_total_count = 0; /* total line count on page */
- Xint set_point_size = 0; /* point size */
- Xint set_char_count = 0; /* characters on a line */
- Xint set_paper_bin = 0; /* paper bin (not page size) */
- Xchar header_text[100]; /* header line text */
- X
- Xint print_attribute = 0; /* such as BOLD, UNDERLINE, ITALICS */
- Xint default_font_number; /* set with -f option, or 0 */
- Xint default_point_size; /* assumes value due to -p option */
- Xint y_coord = 0; /* current logical page y-coordinate, points*/
- Xint x_coord = 0; /* current logical page x-coordinate, points*/
- Xint page_number; /* current page number for this file */
- Xint physical_page = 0; /* postscript physical page for multi-up */
- Xint print_postscript = 0; /* force print of postscript */
- Xint remove_beginning = 0; /* remove lines at beginning of job */
- Xint remove_between = 0; /* remove lines between printed pages */
- Xint is_a_formfeed = 0; /* skip to top of page caused by formfeed */
- Xint end_of_file = 0; /* end of printing file */
- Xint save_point_size ; /* save original point size for headers */
- Xint n_chars; /* number of characters on a line */
- Xint reverse_order = 0; /* print in reverse_order */
- Xint reverse_requested = 0; /* user option for reverse order */
- Xchar fname[100];
- Xchar now[50]; /* time of day for page headers */
- X
- X#ifdef HOPPER
- Xint hopper_available = 1;
- X#else
- Xint hopper_available = 0;
- X#endif
- X
- X/* to select a font, use 4 * font_number + print_attribute as index.
- X
- X Helvetica-Bold = fonts[4 * 1 + 2]
- X = fonts [4 * 1 + ITALICS | BOLD]
- X
- X If one of the following fonts is found in "psfprint.def", then it is
- X flagged as "available" (fonts_have[i] = 1), if not, it is
- X "unavailable". This font list should include all known adobe fonts.
- X*/
- X
- X#define NFONTS 144 /* 4 variations * 36 font families */
- X
- Xint font_count = 48; /* 4 * 12 default fonts for fonts below */
- Xchar *fonts[NFONTS] =
- X{
- X /* base font italics font bold font bold-italics */
- X
- X "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique",
- X "Helvetica", "Helvetica-Oblique", "Helvetica-Bold", "Helvetica-BoldOblique",
- X "Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic",
- X "AvantGarde-Book", "AvantGarde-BookOblique", "AvantGarde-Demi", "AvantGarde-DemiOblique",
- X "Bookman-Light", "Bookman-LightItalic", "Bookman-Demi", "Bookman-DemiItalic",
- X "NewCenturySchlbk-Roman", "NewCenturySchlbk-Italic", "NewCenturySchlbk-Bold", "NewCenturySchlbk-BoldItalic",
- X "Palatino-Roman", "Palatino-Italic", "Palatino-Bold", "Palatino-BoldItalic",
- X "Helvetica-Narrow", "Helvetica-Narrow-Oblique", "Helvetica-Narrow-Bold", "Helvetica-Narrow-BoldOblique",
- X "Garamond-Light", "Garamond-LightItalic", "Garamond-Bold", "Garamond-BoldItalic",
- X "Korinna-Regular", "Korinna-KursivRegular", "Korinna-Bold", "Korinna-KursivBold",
- X "Helvetica-Condensed", "Helvetica-Condensed-Oblique", "Helvetica-Condensed-Bold", "Helvetica-Condensed-BoldObl",
- X "ZapfChancery-MediumItalic","ZapfChancery-MediumItalic","ZapfChancery-MediumItalic","ZapfChancery-MediumItalic"
- X} ;
- X
- Xint fonts_used[NFONTS];
- Xint fonts_have[NFONTS];
- Xunsigned char xlate[256]; /* translation vector */
- Xint need_xlate = 0; /* no default xlate */
- Xchar copyfile[150]; /* copy file name from psfprint.def */
- X
- Xint max_frame = 1; /* max number of frames in use */
- Xint frame = -1; /* current frame in use */
- X
- XFILE *input_fp, *output_fp;
- X
- X/* input line and input line pointer */
- Xchar *c;
- Xchar line[LONG_STR + 1];
- X
- Xchar *pgmname;
- X
- Xvoid catch();
- Xjmp_buf eof_env;
- X
- Xchar *defref = NULL;
- XFILE *pdef = NULL; /* psfprint.def file */
- X
- Xchar *ascii_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
- Xextern int atoi(), getpid();
- X
- X/****************************************************************************
- X* main () *
- X****************************************************************************/
- X
- Xmain (argc, argv)
- Xint argc;
- Xchar *argv[];
- X{ int c, i, j, number;
- X extern char *optarg;
- X extern int optind, getopt();
- X char bookfile[100];
- X char *env_fname; /* environment specified output file */
- X char *getenv();
- X int narrow2x;
- X char alt_cmd[200];
- X
- X if ((pgmname = strrchr (argv[0], '/'))
- X || (pgmname = strrchr (argv[0], '\\'))
- X || (pgmname = strrchr (argv[0], ':')))
- X pgmname++;
- X else
- X pgmname = argv[0];
- X
- X copyfile[0] = 0;
- X for (i = 0; i < 256; i++) /* initial xlate = no translation */
- X xlate[i] = i;
- X for (i = font_count; i < NFONTS; i++)
- X fonts[i] = "N/A";
- X
- X for (i = 0; i < argc; i++) /* if user sets -u alt.def */
- X { if (strncmp (argv[i], "-u", 2) == 0)
- X { if (strlen (argv[i]) > 2)
- X defref = argv[i] + 2;
- X else
- X defref = argv[i+1];
- X break;
- X }
- X }
- X if (i >= argc)
- X { if ((defref = getenv ("PSFDEF")) == NULL)
- X defref = PDEF;
- X }
- X
- X /* Read the .def file if it exists */
- X
- X alt_cmd[0] = '\0';
- X if ((pdef = fopen (defref, "r")) != NULL)
- X { char line_type[50];
- X#if defined(FORLPD)
- X char *quote, *word;
- X int modified_argv = 0;
- X
- X /* read lpd options from psfprint.def. Format is:
- X *psflpd argv0name opt1 opt2 opt3...
- X */
- X while (fgets (alt_cmd, 200, pdef))
- X { if (*alt_cmd == '#')
- X continue;
- X alt_cmd[199] = '\0';
- X trim (alt_cmd);
- X word = strtok (alt_cmd, " \t");
- X if (strcmp (word, "*psflpd") == 0)
- X { word = strtok (NULL, " \t");
- X if (strcmp (word, pgmname) == 0)
- X { argv = (char **) malloc (sizeof (char *) * 50);
- X argv[0] = word;
- X modified_argv = 1;
- X for (argc = 1; word = strtok (NULL, " \t"); argc++)
- X { if (*word == '#') /* quite on comments */
- X break;
- X argv[argc] = word;
- X }
- X argv[argc] = NULL;
- X break;
- X }
- X }
- X else if (strcmp (word, "*printer") == 0)
- X break;
- X }
- X if (modified_argv == 0)
- X { argc = 1;
- X argv[1] = NULL;
- X }
- X
- X#endif /* FORLPD */
- X
- X /* skip to printer definition */
- X if (strncmp (alt_cmd, "*printer", 8))
- X { while (fgets (line, 200, pdef))
- X { if (strncmp (line, "*printer", 8) == 0)
- X break;
- X }
- X }
- X nslots = 0;
- X fgets (line, 200, pdef); /* skip printer name */
- X while (fgets (line, 200, pdef))
- X { trim (line);
- X sscanf (line, "%s%d", line_type, &number);
- X
- X if (strcmp (line_type, "*paper") == 0)
- X { for (i = j = 0; i < number; i++)
- X { if (i >= NPAGE - 1)
- X { fgets (line, 200, pdef);
- X fgets (line, 200, pdef);
- X fgets (line, 200, pdef);
- X continue;
- X }
- X if (fgets (line, 200, pdef) == NULL)
- X bad_file();
- X line[59] = 0;
- X trim (line);
- X strcpy (page_types[i].paper_name, line);
- X if (fgets (line, 99, pdef) == NULL)
- X bad_file();
- X line[99] = 0;
- X trim (line);
- X strcpy (page_types[i].paper_tray, line);
- X if (fgets (line, 100, pdef) == NULL)
- X bad_file();
- X trim (line);
- X sscanf (line, "%d%d%d%d%d%d",
- X &page_types[i].width, &page_types[i].height,
- X &page_types[i].lx, &page_types[i].ly,
- X &page_types[i].ux, &page_types[i].uy);
- X j = i;
- X }
- X page_types[j+1].paper_name[0] = '\0';
- X }
- X
- X else if (strcmp (line_type, "*order") == 0)
- X { fgets (line, 200, pdef);
- X line[19] = 0;
- X trim (line);
- X strcpy (order_default, line);
- X if (number > 1)
- X { if (fgets (line, 200, pdef) == NULL)
- X bad_file();
- X trim (line);
- X line[99] = 0;
- X strcpy (order_normal, line);
- X if (fgets (line, 200, pdef) == NULL)
- X bad_file();
- X trim (line);
- X line[99] = 0;
- X strcpy (order_reverse, line);
- X }
- X }
- X
- X else if (strcmp (line_type, "*fonts") == 0)
- X { for (i = 0; i < NFONTS; i++)
- X fonts_have[i] = 0;
- X for (i = 0; i < number; i++)
- X { if (fgets (line, 200, pdef) == NULL)
- X bad_file();
- X trim (line);
- X for (j = 0; j < font_count; j++)
- X { if (compare (fonts[j], line) == 0)
- X { fonts_have[j] = 1;
- X break;
- X }
- X }
- X }
- X }
- X
- X else if (strcmp (line_type, "*slots") == 0)
- X { for (j = 0; j < NSLOTS; j++)
- X slots[j][0] = 0;
- X for (i = j = 0; i < number; i++)
- X { if (fgets (line, 200, pdef) == NULL)
- X bad_file();
- X if (i >= NSLOTS)
- X continue;
- X line[99] = 0;
- X trim (line);
- X strcpy (slots[i], line);
- X j = i;
- X }
- X nslots = j + 1;
- X }
- X
- X else if (strcmp (line_type, "*eof") == 0)
- X break;
- X else
- X bad_file();
- X }
- X replacement_fonts ();
- X }
- X else /* if no .def, assume all fonts exist */
- X { for (i = 0; i < font_count; i++)
- X fonts_have[i] = 1;
- X }
- X
- X for (i = 0; page_types[i].paper_name[0]; i++)
- X { page_types[i].left_marg = page_types[i].lx;
- X page_types[i].bot_marg = page_types[i].ly;
- X page_types[i].top_marg = (page_types[i].height - 1) - page_types[i].uy;
- X page_types[i].right_marg = (page_types[i].width - 1) - page_types[i].ux;
- X
- X page_types[i].x_size = page_types[i].ux - page_types[i].lx + 1;
- X page_types[i].y_size = page_types[i].uy - page_types[i].ly + 1;
- X }
- X
- X#ifdef PAPERTYPE
- X for (i = 0; page_types[i].paper_name[0]; i++)
- X { if (strcmp (page_types[i].paper_name, PAPERTYPE) == 0)
- X { p = &page_types[i];
- X break;
- X }
- X }
- X if (page_types[i].paper_name[0] == '\0')
- X p = &page_types[0];
- X#else
- X p = &page_types[0]; /* default to letter size paper */
- X#endif /* PAPERTYPE */
- X
- X *header_text = '\0';
- X if (argc > 1 && (strcmp (argv[1], "-") == 0 || strcmp (argv[1], "--") == 0))
- X usage();
- X
- X narrow2x = 0;
- X while ((c = getopt(argc, argv, "124xhnwdvzsi:m:b:c:g:H:l:L:f:t:p:r:R:u:-?")) != -1)
- X { switch (c)
- X {
- X case '1':
- X max_frame = 1;
- X break;
- X
- X case '2':
- X if (narrow2x == 0)
- X landscape = 1;
- X max_frame = 2;
- X break;
- X
- X case '4':
- X max_frame = 4;
- X break;
- X
- X case 'b':
- X if ((set_paper_bin = atoi (optarg)) > nslots)
- X { if (nslots = 0)
- X fprintf (stderr, "%s: no alternate bins permitted\n", nslots);
- X else
- X fprintf (stderr, "%s: paper bin greater than %d\n", pgmname, nslots);
- X exit (1);
- X }
- X break;
- X
- X case 'c':
- X chars_on_line = atoi (optarg);
- X set_char_count = 1;
- X break;
- X
- X case 'd':
- X book = 1;
- X break;
- X
- X case 'f':
- X if (*optarg > '9' && optarg[1]) /* at least 2 chars */
- X { /* character string name of font */
- X for (i = 0; i < font_count; i += 4)
- X { if (partial_compare (optarg, fonts[i]) == 0)
- X { font_number = i / 4;
- X break;
- X }
- X }
- X if (i >= font_count)
- X font_number = 0;
- X }
- X else
- X { /* single digit hex */
- X font_number = xtoi ((int) *optarg);
- X if (font_number > (font_count / 4))
- X font_number = 0;
- X }
- X break;
- X
- X case 'g':
- X p = NULL;
- X for (i = 0; page_types[i].paper_name[0]; i++)
- X { if (compare (optarg, page_types[i].paper_name) == 0)
- X { p = &page_types[i];
- X break;
- X }
- X }
- X if (p == NULL)
- X usage ();
- X set_paper_tray = 1;
- X break;
- X
- X case 'h':
- X header = 1;
- X break;
- X
- X case 'H':
- X header = 2;
- X strcpy (header_text, optarg);
- X break;
- X
- X case 'i':
- X x_user_offset = atoi (optarg);
- X break;
- X
- X case 'l':
- X lines_on_page = atoi (optarg);
- X set_line_count = 1;
- X break;
- X
- X case 'L':
- X lines_total = atoi (optarg);
- X set_total_count = 1;
- X break;
- X
- X case 'm':
- X y_user_offset = atoi (optarg);
- X break;
- X
- X case 'n':
- X landscape = 0;
- X narrow2x = 1;
- X break;
- X
- X case 'p':
- X point_size = atoi (optarg);
- X set_point_size = 1;
- X break;
- X
- X case 'r':
- X remove_between = atoi (optarg);
- X break;
- X
- X case 'R':
- X remove_beginning = atoi (optarg);
- X break;
- X
- X case 's':
- X size_display();
- X exit (1);
- X
- X case 't':
- X tab_size = atoi (optarg);
- X break;
- X
- X case 'u': /* already processed */
- X break;
- X
- X case 'v':
- X reverse_requested = 1;
- X break;
- X
- X case 'w':
- X landscape = 1;
- X break;
- X
- X case 'x':
- X cross = 1;
- X break;
- X
- X case 'z':
- X print_postscript = 1;
- X break;
- X
- X default: usage ();
- X break;
- X }
- X }
- X
- X if (strncmp (order_default, "Reverse", 7) == 0) /* stacking sequence */
- X reverse_order = 1; /* "Reverse" */
- X else
- X reverse_order = 0; /* "Normal" */
- X if (reverse_requested) /* User wants reverse ? */
- X reverse_order = !reverse_order; /* yes */
- X if (reverse_order && order_reverse[0]) /* Reverse tray command */
- X { order_command = order_reverse; /* yes */
- X reverse_order = 0; /* order_command does the work*/
- X }
- X else if (reverse_order == 0 && order_normal[0]) /* Force normal order tray?*/
- X order_command = order_normal; /* yes */
- X else
- X order_command = NULL; /* use default action */
- X
- X if (reverse_requested && book)
- X { fprintf (stderr, "Double sided or book in reverse ordered not supported\n");
- X exit (1);
- X }
- X
- X
- X if (nslots <= 1)
- X hopper_available = 0;
- X if (reverse_order || (book && hopper_available))
- X sprintf (bookfile, "%s%d.bok", TEMPFILE, getpid());
- X else
- X strcpy (bookfile, BOOKFILE);
- X
- X if (max_frame == 2 && landscape == 0)
- X set_point_size = 1;
- X if (optind >= argc && header == 1) /* no file name header on stdin */
- X header = 0;
- X save_point_size = point_size;
- X
- X (void) signal (SIGINT, catch); /* for lpd quit */
- X
- X
- X#ifdef PSFFILTER
- X
- X output_fp = stdout;
- X input_fp = stdin;
- X if (header == 1)
- X strcpy (fname, argv[optind]);
- X else
- X *fname = 0;
- X
- X if (fgets (line, LONG_STR, input_fp) == NULL)
- X exit (0);
- X if (tscan (line, "%!") >= 0 && print_postscript == 0)
- X { /* already postscript copy to output */
- X if (fputs (line, output_fp) == EOF)
- X output_trouble (2);
- X while ((i = fgetc (input_fp)) != EOF)
- X { if (fputc (i, output_fp) == EOF)
- X output_trouble (2);
- X }
- X }
- X else
- X { /* standard postscript conversion for file on stdin */
- Xbannerdone:
- X if (font_number * 4 > font_count)
- X { fprintf (stderr,"Font number invalid....\n");
- X usage ();
- X }
- X
- X if (book || reverse_order)
- X { if ((output_fp = fopen (bookfile, "w")) == NULL)
- X { fprintf (stderr, "%s: cannot create work file\n", pgmname);
- X exit (1);
- X }
- X if ((pg_loc = (long *) malloc (sizeof (long) * MAX_PAGES)) == NULL)
- X { fprintf (stderr, "%s: cannot allocate enough memory\n", pgmname);
- X exit (1);
- X }
- X npg_loc = 0;
- X }
- X
- X for (i = 0; i < NFONTS; i++)
- X fonts_used[i] = 0;
- X
- X page_number = -1;
- X line_number = 32000;
- X default_point_size = point_size;
- X default_font_number = font_number;
- X bookwork = book && landscape && (max_frame == 2);
- X
- X input_fp = stdin;
- X get_time (now);
- X scale_factors ();
- X prologue ();
- X start_file ();
- X process_file ();
- X terminate_printer ();
- X output_book (bookfile);
- X }
- X
- X#else /* not PSFFILTER */
- X
- X /* begin normal "psf" code */
- X
- X if (font_number * 4 > font_count)
- X { fprintf (stderr,"Font number invalid....\n");
- X usage ();
- X }
- X
- X if (book || reverse_order)
- X { if ((output_fp = fopen (bookfile, "w")) == NULL)
- X { fprintf (stderr, "%s: cannot create work file\n", pgmname);
- X exit (1);
- X }
- X if ((pg_loc = (long *) malloc (sizeof (long) * MAX_PAGES)) == NULL)
- X { fprintf (stderr, "%s: cannot allocate enough memory\n", pgmname);
- X exit (1);
- X }
- X npg_loc = 0;
- X }
- X else
- X { if (env_fname = getenv ("PSFLP"))
- X#if defined(MSDOS) || defined (__MSDOS__)
- X { if ((output_fp = fopen (env_fname, "wt")) == NULL)
- X#else
- X { if ((output_fp = fopen (env_fname, "w")) == NULL)
- X#endif
- X { fprintf (stderr, "Cannot open output file %s\n", env_fname);
- X exit (1);
- X }
- X }
- X else
- X { output_fp = stdout;
- X }
- X }
- X
- X
- X for (i = 0; i < NFONTS; i++)
- X fonts_used[i] = 0;
- X
- X page_number = -1;
- X line_number = 32000;
- X default_point_size = point_size;
- X default_font_number = font_number;
- X bookwork = book && landscape && (max_frame == 2);
- X *fname = 0;
- X
- X get_time (now);
- X scale_factors ();
- X prologue ();
- X if (optind >= argc) /* process on stdin */
- X { input_fp = stdin;
- X start_file ();
- X process_file ();
- X }
- X else
- X { for ( ; optind < argc; optind++) /* files from cmd line */
- X { strcpy (fname, argv[optind]);
- X if ((input_fp = fopen (argv[optind], "r")) == NULL)
- X { fprintf (stderr, "Unknown file: %s\n", argv[optind]);
- X continue;
- X }
- X start_file ();
- X process_file ();
- X fclose (input_fp);
- X }
- X }
- X terminate_printer ();
- X
- X output_book (bookfile);
- X /* end normal psf code */
- X
- X#endif /* PSFFILTER */
- X
- X exit (0);
- X}
- X
- X
- X/****************************************************************************
- X* scale_factors () *
- X* Compute the x and y scale factors. *
- X****************************************************************************/
- X
- X/* total paper size - unprintable size
- X scale factor = --------------------------------------
- X print size
- X*/
- X
- Xvoid scale_factors ()
- X{ int wide; /* width needed for char count */
- X int high; /* points needed for line count */
- X int n_lines; /* number of lines on a page */
- X int i;
- X double char_width, scale;
- X double char_sf, line_sf;
- X int nominal_high, nominal_wide;
- X int on_portrait;
- X
- X /* use either the "portrait" or landscape width/height for basic scaling
- X */
- X switch (max_frame)
- X {
- X case 1: on_portrait = 0;
- X break;
- X case 2: if (landscape)
- X on_portrait = 1;
- X else
- X on_portrait = 0;
- X break;
- X case 4: if (landscape)
- X on_portrait = 0;
- X else
- X on_portrait = 1;
- X }
- X
- X real_width = p->width; /* for initial axis translate only */
- X
- X /* if 4up in portrait or 2up, we want to shrink the image as
- X though it were a proper 8.5x11 page. thus do all calculations
- X of line and column count as though it were a normal portrait page.
- X */
- X if (on_portrait)
- X { nominal_high = p->y_size;
- X nominal_wide = p->x_size;
- X }
- X if (landscape)
- X {
- X i = p->height; p->height = p->width; p->width = i;
- X i = p->left_marg; p->left_marg = p->bot_marg; p->bot_marg = i;
- X i = p->top_marg; p->top_marg = p->right_marg; p->right_marg = i;
- X i = p->lx; p->lx = p->ly; p->ly = i;
- X i = p->ux; p->ux = p->uy; p->uy = i;
- X i = p->x_size; p->x_size = p->y_size; p->y_size = i;
- X }
- X if (on_portrait == 0)
- X { nominal_high = p->y_size;
- X nominal_wide = p->x_size;
- X }
- X
- X if (set_point_size)
- X { /* if point size specified, ignore changes to rows and columns
- X with -L, -l & -c. They destroy character shape.
- X */
- X char_width = point_size / 12.0 * NOMINAL_CWIDE;
- X n_chars = ceil ((double) nominal_wide / (double) char_width);
- X n_lines = (double) nominal_high / (double) point_size;
- X char_sf = 1.0;
- X line_sf = 1.0;
- X
- X if (set_total_count == 0 || lines_total > n_lines)
- X lines_total = n_lines;
- X if (set_line_count == 0 || lines_on_page > n_lines)
- X lines_on_page = n_lines;
- X if (lines_total < lines_on_page)
- X lines_on_page = lines_total;
- X if (header) /* compress scale to allow headers */
- X { lines_on_page += 2;
- X lines_total += 2;
- X line_sf = (double) n_lines / (double) lines_total;
- X }
- X }
- X else
- X { /* determine independent scale factors to lines and columns
- X based on user line and column count. This changes
- X the character aspect ration - squashing it vertically
- X and/or horizontally.
- X */
- X char_width = NOMINAL_CWIDE;
- X n_chars = ceil ((double) nominal_wide / (double) char_width);
- X
- X if (set_char_count)
- X char_sf = (double) n_chars / (double) chars_on_line;
- X else
- X { char_sf = 1.0; /* no change to char count */
- X chars_on_line = n_chars;
- X }
- X
- X n_lines = (double) nominal_high / (double) point_size;
- X
- X if (set_total_count == 0)
- X lines_total = n_lines;
- X if (set_line_count == 0)
- X lines_on_page = n_lines;
- X if (lines_total < lines_on_page)
- X { if (set_total_count)
- X lines_on_page = lines_total;
- X else
- X lines_total = lines_on_page;
- X }
- X if (header) /* compress scale to allow headers */
- X { lines_on_page += 2;
- X lines_total += 2;
- X }
- X line_sf = (double) n_lines / (double) lines_total;
- X }
- X
- X /* theoretical points high and wide that we would "like" to
- X have for our page - before scaling - including a 1/2 line
- X for descenders for the last line.
- X */
- X high = ceil ((double) point_size * ((double) n_lines + 0.51));
- X wide = ceil (n_chars * char_width);
- X
- X x_user_offset = max (0, x_user_offset - p->left_marg);
- X y_user_offset = max (0, y_user_offset - p->top_marg );
- X
- X switch (max_frame)
- X {
- X case 1:
- X scale_x = (double) (p->x_size) / (double) wide * char_sf;
- X scale_y = (double) (p->y_size) / (double) high * line_sf;
- X x_left_offset = (int) ceil ((double) (p->left_marg + x_user_offset) / scale_x);
- X y_top_offset = (int) ceil ((double) (p->top_marg + y_user_offset) / scale_y);
- X dx_home[0] = 0;
- X dy_home[0] = 0;
- X p->height = ceil ((double) p->height / scale_y);
- X p->width = ceil ((double) p->width / scale_x);
- X p->bot_marg = ceil ((double) p->bot_marg / scale_y);
- X break;
- X
- X case 2:
- X scale_x = (double) (p->width - 2 * p->left_marg - 2 * p->right_marg)
- X / (double) (2 * wide) * char_sf;
- X scale_y = (double) (p->y_size) / (double) high * line_sf;
- X
- X if (landscape == 0)
- X { scale_y /= 2.0;
- X lines_total *= 2.0;
- X lines_on_page *= 2.0;
- X }
- X
- X /* point offsets for margins account for physical "forbidden" area */
- X
- X x_left_offset = (int) ceil ((double) p->left_marg / scale_x);
- X y_top_offset = (int) ceil ((double) p->top_marg / scale_y);
- X
- X /* page origin translation vectors */
- X
- X p->height = ceil ((double) p->height / scale_y);
- X p->width = ceil ((double) p->width / (scale_x * 2.0));
- X p->bot_marg = ceil ((double) p->bot_marg / scale_y);
- X dx_home[0] = 0;
- X dy_home[0] = 0;
- X dx_home[1] = p->width;
- X dy_home[1] = 0;
- X break;
- X
- X case 4:
- X scale_x = (double) (p->width - 2 * p->left_marg - 2 * p->right_marg)
- X / (double) (2 * wide) * char_sf;
- X scale_y = (double) (p->height - 2 * p->top_marg - 2 * p->bot_marg)
- X / (double) (2 * high) * line_sf;
- X
- X /* point offsets for margins account for physical "forbidden" area */
- X
- X x_left_offset = (int) ceil ((double) p->left_marg / scale_x);
- X y_top_offset = (int) ceil ((double) p->top_marg / scale_y);
- X
- X /* page origin tranlsation vectors */
- X
- X p->height = ceil ((double) p->height / (scale_y * 2.0));
- X p->width = ceil ((double) p->width / (scale_x * 2.0));
- X p->bot_marg = ceil ((double) p->bot_marg / scale_y);
- X dx_home[0] = 0;
- X dy_home[0] = p->height;
- X dx_home[1] = p->width;
- X dy_home[1] = 0;
- X dx_home[2] = -p->width;
- X dy_home[2] = -p->height;
- X dx_home[3] = p->width;
- X dy_home[3] = 0;
- X break;
- X
- X default: ;
- X }
- X
- X if (max_frame > 1)
- X { x_left_offset += x_user_offset;
- X y_top_offset += y_user_offset;
- X }
- X}
- X
- X
- X/****************************************************************************
- X* prologue () *
- X* generate the require postscript-conformant prologue *
- X****************************************************************************/
- X
- Xvoid prologue ()
- X{ char *getlogin(), *me;
- X int c;
- X FILE *fp;
- X
- X if (book || reverse_order)
- X fprintf (output_fp, "%%Book file: psf-to-psfdoub\n");
- X else
- X fprintf (output_fp, "%%!PS-Adobe-\n");
- X#if !defined(MSDOS) && !defined(__MSDOS__)
- X me = getlogin();
- X if (me == NULL) /* AT&T Unix 3.2 getlogin() is broken */
- X#endif
- X me = "psf"; /* could use cuserid() instead */
- X fprintf (output_fp, "%%%%Creator: %s\n", me);
- X fprintf (output_fp, "%%%%CreationDate: %s\n", now);
- X fprintf (output_fp, "%%%%DocumentFonts: (atend)\n");
- X fprintf (output_fp, "%%%%Pages: (atend)\n");
- X fprintf (output_fp, "%%%%EndComments\n");
- X
- X /* usage: (text to underline) <pointsize> showuline
- X where: <pointsize> is current text point size.
- X
- X eg: (text to underline) 12 showuline
- X */
- X fprintf (output_fp, "%s%s%s%s%s%s%s%s%s%s%s",
- X "/showuline {\n",
- X " /CurPointSize exch def\n",
- X " dup stringwidth pop\n",
- X " gsave\n",
- X " currentfont /FontInfo get dup\n",
- X " /UnderlinePosition get CurPointSize mul 1000 div 0 exch rmoveto exch 0 rlineto\n",
- X " /UnderlineThickness get CurPointSize mul 1000 div setlinewidth stroke\n",
- X " grestore\n",
- X " show\n",
- X "} def\n",
- X "/mv {moveto} def\n");
- X
- X /* add additional startup prologue code from psfprint.def
- X probably for non-English language support.
- X */
- X if (pdef)
- X { while (fgets (line, LONG_STR, pdef))
- X { if (fputs (line, output_fp) == EOF)
- X output_trouble (2);
- X }
- X fclose (pdef);
- X pdef = NULL;
- X }
- X
- X /* copy a copyfile requested from psfprint.def */
- X
- X if (copyfile[0])
- X { if (fp = fopen (copyfile, "r"))
- X { while (1)
- X { c = fgetc (fp);
- X if (feof (fp) || ferror (fp))
- X break;
- X if (fputc (c, fp) == EOF)
- X output_trouble (2);
- X }
- X fclose (fp);
- X }
- X }
- X
- X fprintf (output_fp, "%%%%EndProlog\n");
- X
- X if (set_paper_tray)
- X fprintf (output_fp, "%s\n", p->paper_tray);
- X
- X if (order_command)
- X fprintf (output_fp, "%s\n", order_command);
- X else if (set_paper_bin)
- X fprintf (output_fp, "%s\n", slots[set_paper_bin - 1]);
- X}
- X
- X/****************************************************************************
- X* showpage () *
- X* Generate a real "showpage" if we have really finished generating a *
- X* physical page. If we are processing 2 or 4 up, then generate *
- X* coordinate "translates" if we really haven't finished all possible *
- X* page frames of the page. *
- X****************************************************************************/
- X
- Xvoid showpage (end_of_file)
- Xint end_of_file;
- X{ int skipping;
- X
- X line_number = 0;
- X
- X if (max_frame > 1)
- X fprintf (output_fp, "grestore\n");
- X
- X if (is_a_formfeed) /* don't skip if caused by form feed */
- X is_a_formfeed = 0; /* needed for lpr of= processing */
- X else if (page_number > 0 && end_of_file == 0)
- X { skipping = remove_between;
- X while (skipping-- && fgets (line, LONG_STR, input_fp))
- X ;
- X if (skipping >= 0)
- X { end_of_file = 1;
- X if (bookwork == 0) /* psfdoub will re-insert this */
- X fprintf (output_fp, "showpage pg restore\n");
- X frame = 0;
- X longjmp (eof_env, 1);
- X }
- X }
- X
- X if (++frame >= max_frame || end_of_file)
- X { if (bookwork == 0) /* psfdoub will re-insert this */
- X fprintf (output_fp, "showpage pg restore\n");
- X frame = 0;
- X }
- X if (!end_of_file)
- X set_frame ();
- X
- X}
- X
- X/****************************************************************************
- X* set_frame () *
- X* Select the next logical frame in two-up or four-up mode. If it is *
- X* the first frame of a physical page, the generate the %%Page *
- X****************************************************************************/
- X
- Xvoid set_frame ()
- X{
- X if (frame == 0 || bookwork)
- X { if (book || reverse_order) /* mark byte position of %%Page: for psfdoub */
- X { pg_loc[npg_loc++] = ftell (output_fp);
- X }
- X fprintf (output_fp, "%%%%Page: ? %d\n", ++physical_page);
- X if (bookwork == 0) /* psfdoub will re-insert these */
- X { fprintf (output_fp, "/pg save def\n");
- X if (landscape)
- X fprintf (output_fp, "90 rotate 0 %d translate\n", -real_width);
- X fprintf (output_fp, "%.5f %.5f scale\n", scale_x, scale_y);
- X }
- X findfont();
- X }
- X
- X set_y_coord ();
- X
- X if (max_frame > 1 && bookwork == 0)
- X fprintf (output_fp, "%d %d translate\n", dx_home[frame], dy_home[frame]);
- X
- X if (frame == 0 && cross)
- X draw_cross();
- X
- X if (max_frame > 1)
- X { fprintf (output_fp, "gsave\n");
- X set_clip_path (0, 0, p->width, p->height);
- X }
- X}
- X
- X
- X/****************************************************************************
- X* set_y_coord *
- X* position next line to the top of a logical page. *
- X*****************************************************************************/
- X
- Xvoid set_y_coord ()
- X{
- X y_coord = p->height - y_top_offset - point_size;
- X}
- X
- X/****************************************************************************
- X* put_top *
- X* put a header line at the top of the page *
- X*****************************************************************************/
- X
- Xvoid put_top ()
- X{ int save_attr, save_point, nc;
- X char fmt[50], *hd;
- X
- X save_attr = print_attribute;
- X save_point = point_size;
- X print_attribute = BOLD;
- X point_size = save_point_size;
- X
- X hd = (header == 1) ? fname : header_text;
- X nc = n_chars - 33;
- X if (nc < strlen (hd))
- X nc = strlen (hd) + 3;
- X sprintf (fmt, "(%%-%ds%%3d %%s)show\n", nc);
- X
- X findfont();
- X moveto (0, y_coord, 1);
- X fprintf (output_fp, fmt, hd, page_number + 1, now);
- X y_coord -= point_size * 2;
- X x_coord = 0;
- X print_attribute = save_attr;
- X point_size = save_point;
- X findfont();
- X}
- X
- X/****************************************************************************
- X* process_file() *
- X* Read the file, look for escape sequences, put text in postscript form *
- X****************************************************************************/
- X
- Xvoid process_file ()
- X{ int char_type, char_count, i, set_page, esc_type;
- X char *strchr ();
- X int previous_attribute;
- X int lcount = 0;
- X unsigned char *xln;
- X
- X set_page = 0;
- X i = remove_beginning;
- X while (i-- && fgets (line, LONG_STR, input_fp))
- X ;
- X if (i >= 0)
- X { showpage (1);
- X return;
- X }
- X
- X if (setjmp (eof_env))
- X { return;
- X }
- X
- X#ifdef PSFFILTER
- X /* psffilter already has a first line, psf does not */
- X do
- X#else
- X while (fgets (line, LONG_STR, input_fp) != NULL)
- X#endif
- X {
- X if (*line == CTLD_EOJ) /* printing postscript code: ^D at end */
- X break; /* assume it is end of file also */
- X
- X if (lcount++ == 0)
- X { if ((i = tscan (line, "ta=")) >= 0)
- X { tab_size = atoi (line + i + 3);
- X }
- X }
- X
- X if (need_xlate) /* translate character set? */
- X { xln = (unsigned char *) line;
- X while (*xln)
- X { i = *xln;
- X *xln++ = xlate[i];
- X }
- X }
- X
- X if ((c = strchr (line, '\f')) != NULL)
- X { if (c == line)
- X { line_number = 32000;
- X c = line + 1;
- X }
- X else
- X { *c = 0;
- X set_page = 1;
- X c = line;
- X }
- X is_a_formfeed = 1;
- X }
- X else
- X c = line;
- X
- X if (line_number >= lines_on_page * 10)
- X { page_number++;
- X showpage (0);
- X line_number = 10;
- X if (header)
- X { put_top();
- X line_number += 20;
- X }
- X }
- X else
- X line_number += 10;
- X
- X char_type = char_count = 0;
- X
- X /* for empty lines, don't generate a real moveto - but to call
- X to ensure that check for page overflow is done.
- X */
- X if (*c == '\n')
- X moveto (x_coord, y_coord, 0); /* don't gen moveto */
- X else
- X moveto (x_coord, y_coord, 1); /* do gen moveto */
- X
- X while (*c && *c != '\n')
- X { if (char_type == 0)
- X { if (fputc ('(', output_fp) == EOF)
- X output_trouble (2);
- X }
- X switch ((int) *c)
- X {
- X case ESCAPE:
- X previous_attribute = print_attribute;
- X esc_type = *(++c);
- X if (escape_sequence (esc_type) == 0)
- X { switch (esc_type)
- X {
- X case 'u':
- X SHOWU (output_fp, point_size);
- X break;
- X
- X default:
- X if (char_type && (previous_attribute & UNDERLINE))
- X SHOWU (output_fp, point_size);
- X else
- X { if (fputs (")show\n", output_fp) == EOF)
- X output_trouble (2);
- X }
- X if (esc_type == '+' || esc_type == '-')
- X { /* check for +/- 1/2 line feed */
- X if (esc_type == '+')
- X y_coord -= point_size / 2;
- X else
- X y_coord += point_size / 2;
- X moveto (x_coord, y_coord, 1);
- X char_type = -1;
- X c++;
- X if (*c != '\n')
- X { if (fputc ('(', output_fp) == EOF)
- X output_trouble (2);
- X }
- X continue;
- X }
- X else
- X findfont ();
- X }
- X char_type = 0;
- X }
- X break;
- X
- X default:
- X if (*c == '\t')
- X { fputc (' ', output_fp);
- X while (++char_count % tab_size)
- X { if (fputc (' ', output_fp) == EOF)
- X output_trouble (2);
- X }
- X }
- X else
- X { if (strchr ("\r\b\\()", *c) != NULL)
- X if (fputc ('\\', output_fp) == EOF)
- X output_trouble (2);
- X if (fputc (*c, output_fp) == EOF)
- X output_trouble (2);
- X char_count++;
- X }
- X char_type = 1;
- X break;
- X }
- X c++;
- X }
- X if (char_type == 1)
- X { if (print_attribute & UNDERLINE)
- X SHOWU (output_fp, point_size);
- X else
- X { if (fputs (")show\n", output_fp) == EOF)
- X output_trouble (2);
- X }
- X }
- X
- X y_coord -= point_size;
- X x_coord = 0;
- X if (set_page)
- X { line_number = 32000;
- X set_page = 0;
- X }
- X#ifdef PSFFILTER
- X } while (fgets (line, LONG_STR, input_fp) != NULL);
- X#else
- X }
- X#endif
- X if (end_of_file == 0)
- X showpage (1);
- X}
- X
- X/****************************************************************************
- X* escape_sequence () *
- X* If an escape sequence (esc,char) is found, mark which type of font *
- X****************************************************************************/
- X
- Xint escape_sequence (which)
- Xint which;
- X{ char s[10];
- X
- X switch (which)
- X {
- X case 'I':
- X print_attribute |= ITALICS;
- X break;
- X
- X case 'i':
- X print_attribute &= ~ITALICS;
- X break;
- X
- X case 'B':
- X print_attribute |= BOLD;
- X break;
- X
- X case 'b':
- X print_attribute &= ~BOLD;
- X break;
- X
- X case 'U':
- X print_attribute |= UNDERLINE;
- X break;
- X
- X case 'u':
- X print_attribute &= ~UNDERLINE;
- X break;
- X
- X case 'F':
- X s[0] = *(++c);
- X s[1] = '\0';
- X font_number = xtoi ((int) *s);
- X if (font_number > (font_count / 4))
- X font_number = (font_count / 4) - 1;
- X break;
- X
- X case 'f':
- X font_number = default_font_number;
- X break;
- X
- X case 'P':
- X s[0] = *(++c);
- X s[1] = *(++c);
- X s[2] = '\0';
- X point_size = atoi (s);
- X break;
- X
- X case 'p':
- X point_size = default_point_size;
- X break;
- X
- X case '+':
- X case '-':
- X break;
- X
- X default:
- X return (-1);
- X ;
- X }
- X return (0);
- X}
- X
- X/****************************************************************************
- X* moveto () *
- X* Generate a postscript x y moveto statememt *
- X****************************************************************************/
- X
- Xvoid moveto (x, y, do_move)
- Xint x;
- Xint y;
- Xint do_move; /* 1 = gen moveto 0 = dont gen moveto */
- X{
- X /* ensure that the current line can fit on the page - including the
- X 1/4 line needed for the decenders
- X */
- X
- X if (line_number > lines_on_page * 10 || y < (p->bot_marg + point_size / 3))
- X { if (line_number < lines_on_page * 10)
- X page_number++;
- X showpage (0);
- X if (header)
- X { put_top();
- X line_number += 20;
- X }
- X y = y_coord;
- X x = x_coord;
- X }
- X
- X if (do_move)
- X fprintf (output_fp, "%d %d mv ", x + x_left_offset, y);
- X}
- X
- X/****************************************************************************
- X* findfont () *
- X* generate a findfont statement *
- X****************************************************************************/
- X
- Xvoid findfont ()
- X{ int this;
- X
- X /* remove reference to UNDERLINE. Underline is not a font. */
- X
- X this = (font_number * 4) + (print_attribute & 0x03);
- X fonts_used[this] = 1;
- X fprintf (output_fp, "/%s findfont %d scalefont setfont\n", fonts[this], point_size);
- X}
- X
- X/****************************************************************************
- X* start_file () *
- X* Generate things that are appropriate for beginning of file processing *
- X****************************************************************************/
- X
- Xvoid start_file ()
- X{
- X end_of_file = 0;
- X line_number = 0;
- X print_attribute = 0;
- X page_number = 0;
- X frame = 0;
- X set_frame ();
- X if (header)
- X { put_top();
- X line_number += 20;
- X }
- X}
- X
- X
- X/****************************************************************************
- X* terminate_printer () *
- X* Generate things that are appropriate wrap-up after all files printed *
- X* For double sided printing (book == 1), generate byte offset info. *
- X****************************************************************************/
- X
- Xvoid terminate_printer ()
- X{ int i, used;
- X long psfptr;
- X
- X if (book || reverse_order)
- X { pg_loc[npg_loc++] = ftell (output_fp);
- X }
- X fprintf (output_fp, "%%%%Trailer\n");
- X for (used = i = 0; i < font_count; i++)
- X { if (fonts_used[i])
- X { used = 1;
- X break;
- X }
- X }
- X if (used)
- X { fprintf (output_fp, "%%%%DocumentFonts:");
- X for (i = 0; i < font_count; i ++)
- X { if (fonts_used[i])
- X fprintf (output_fp, " %s", fonts[i]);
- X }
- X fprintf (output_fp, "\n");
- X }
- X
- X fprintf (output_fp, "%%%%Pages: %d\n", physical_page);
- X
- X if (book || reverse_order) /* print statistics for psfdoub */
- X { psfptr = ftell (output_fp);
- X fprintf (output_fp, "%%PsfScale: %.5f %.5f scale\n", scale_x, scale_y);
- X fprintf (output_fp, "%%PsfMargin: %d %d %d %d %d\n",
- X max_frame, landscape, real_width, p->height, p->width);
- X for (i = 0; i < 4; i++)
- X fprintf (output_fp, "%%PsfHome: %d %d %d\n", i, dx_home[i], dy_home[i]);
- X for (i = 0; i < npg_loc-1; i++)
- X fprintf (output_fp, "%%PsfPg: %d %d\n", i, pg_loc[i]);
- X fprintf (output_fp, "%%PsfPg: 9999 %d\n", pg_loc[npg_loc-1]);
- X fprintf (output_fp, "%%PsfPtr: %d\n", psfptr);
- X }
- X fprintf (output_fp, "%c", CTLD_EOJ); /* CTL/D = end job */
- X}
- X
- X/****************************************************************************
- X* draw_cross () *
- X* Draw horizontal and vertical separation lines between pages 2/4-up *
- X****************************************************************************/
- X
- Xvoid draw_cross ()
- X{ int p_w, p_h;
- X
- X if (max_frame > 1)
- X { p_w = p->width;
- X p_h = p->height;
- X if (max_frame == 4)
- X { set_clip_path (0, -p_h, p_w * 2, p_h);
- X fprintf (output_fp,"gsave %d %d moveto\n", p_w, p_h);
- X fprintf (output_fp,"%d %d lineto\n", p_w, -p_h);
- X fprintf (output_fp,"%d %d moveto\n", 0, 0);
- X fprintf (output_fp,"%d %d lineto\n", p_w * 2, 0);
- X fprintf (output_fp,"%s\n", "stroke grestore");
- X }
- X else
- X { set_clip_path (0, 0, p_w * 2+ 1, p_h + 1);
- X fprintf (output_fp,"gsave %d %d moveto\n", p_w, p_h);
- X fprintf (output_fp,"%d %d lineto\n", p_w, 0);
- X fprintf (output_fp,"%s\n", "stroke grestore");
- X }
- X }
- X}
- X
- X/****************************************************************************
- X* set_clip_path *
- X****************************************************************************/
- X
- Xvoid set_clip_path (x1, y1, x2, y2)
- Xint x1, y1, x2, y2;
- X{
- X x1--; y1--; x2++; y2++;
- X
- X fprintf (output_fp, "newpath\n");
- X fprintf (output_fp,"%d %d moveto\n", x1, y1);
- X fprintf (output_fp,"%d %d lineto\n", x1, y2);
- X fprintf (output_fp,"%d %d lineto\n", x2, y2);
- X fprintf (output_fp,"%d %d lineto\n", x2, y1);
- X fprintf (output_fp,"%s\n", "closepath clip");
- X}
- X
- X/****************************************************************************
- X* output_book () *
- X* Send file "double sided print" mode. Used to make a "book". *
- X****************************************************************************/
- X
- Xvoid output_book (bookfile)
- Xchar *bookfile;
- X{ char opts[50];
- X
- X if (book == 0 && reverse_order == 0)
- X return;
- X
- X#ifdef HOPPER
- X
- X if (nslots > 1 || reverse_order)
- X { if (output_fp != stdout)
- X { fflush (output_fp);
- X fclose (output_fp);
- X
- X sprintf (opts, "%s %s", reverse_requested ? "-v" : "",
- X book ? "-3" : "");
- X
- X#if defined(MSDOS) || defined(__MSDOS__)
- X sprintf (line, "%s %s -u %s %s", PSFDOUB, opts, defref, bookfile);
- X#else
- X sprintf (line, "%s/%s %s -u %s %s", BINDIR, PSFDOUB, opts, defref, bookfile);
- X#endif
- X system (line);
- X unlink (bookfile);
- X }
- X }
- X
- X
- X#else /* not HOPPER */
- X if (reverse_order)
- X { if (output_fp != stdout)
- X { fflush (output_fp);
- X fclose (output_fp);
- X
- X sprintf (opts, "%s", reverse_requested ? "-v" : "");
- X
- X#if defined(MSDOS) || defined(__MSDOS__)
- X sprintf (line, "%s %s -u %s %s", PSFDOUB, opts, defref, bookfile);
- X#else
- X sprintf (line, "%s/%s %s -u %s %s", BINDIR, PSFDOUB, opts, defref, bookfile);
- X#endif
- X system (line);
- X unlink (bookfile);
- X }
- X }
- X
- X
- X#endif /* HOPPER */
- X}
- X
- X
- X/************************************************************************
- X* tscan (s,t) *
- X* look for string t in s. return -1 if t does not exits in s else *
- X* return array position of first character match *
- X************************************************************************/
- X
- Xint tscan (s, t)
- Xchar s[], t[];
- X{
- X int i, j, k;
- X for (i = 0; s[i] != '\0'; i++)
- X { for (j = i, k=0; t[k] != '\0' && s[j] == t[k]; j++, k++)
- X ;
- X if (t[k] == '\0')
- X return (i);
- X }
- X return (-1);
- X}
- X
- Xvoid get_time (t) /* get current time of */
- Xchar *t;
- X{
- X long n_time, time ();
- X char *x_time, *cc, *strchr();
- X
- X n_time = time (0); /* get time */
- X x_time = ctime (&n_time); /* convert ascii */
- X if ((cc = strchr (x_time, '\n')) != NULL)
- X *cc = '\0';
- X strcpy (t, x_time);
- X}
- X
- Xint compare (a,b) /* case insensitive compare */
- Xchar *a, *b;
- X{ int aa, bb;
- X
- X while (*a)
- X { aa = *a++;
- X bb = *b++;
- X if (UCCHAR (aa) != UCCHAR (bb))
- X return (UCCHAR(aa) - UCCHAR(bb));
- X }
- X return (UCCHAR (*a) - UCCHAR (*b));
- X}
- X
- Xint partial_compare (a,b) /* case insensitive compare */
- Xchar *a, *b; /* if all parts of 'a' are successful */
- X{ int aa, bb;
- X
- X while (*a)
- X { aa = *a++;
- X bb = *b++;
- X if (UCCHAR (aa) != UCCHAR (bb))
- X return (UCCHAR(aa) - UCCHAR(bb));
- X }
- X return (0);
- X}
- X
- Xint comparen (a,b, n) /* case insensitive compare with count limit */
- Xchar *a, *b;
- Xint n;
- X{ int aa, bb;
- X
- X while (*a && n--)
- X { aa = *a++;
- X bb = *b++;
- X if (UCCHAR (aa) != UCCHAR (bb))
- X return (UCCHAR(aa) - UCCHAR(bb));
- X }
- X if (n <= 0)
- X return (0);
- X return (UCCHAR (*a) - UCCHAR (*b));
- X}
- X
- Xint endcompare (a,b) /* compare end of a with b */
- Xchar *a, *b;
- X{
- X int na, nb;
- X
- X na = strlen (a);
- X nb = strlen (b);
- X if (na > nb)
- X a += na - nb;
- X return (strcmp (a,b));
- X}
- X
- X
- Xvoid trim (s) /* trim trailing blanks and \n */
- Xchar *s;
- X{ int many;
- X
- X for (many = strlen (s) - 1; many >= 0; many--)
- X { if (isgraph (s[many]))
- X break;
- X else
- X s[many] = '\0';
- X }
- X}
- X
- Xvoid bad_file()
- X{
- X fprintf (stderr, "Bad %s file\n", defref);
- X exit (1);
- X}
- X
- Xint xtoi (c) /* hex character to integer */
- Xint c; /* any letter is a 'hex' digit */
- X{
- X char xc[2];
- X int rv;
- X
- X if (isupper (c))
- X xc[0] = tolower (c);
- X else
- X xc[0] = c;
- X xc[1] = '\0';
- X
- X rv = tscan (ascii_hex, xc);
- X if (rv >= 0)
- X return (rv);
- X return (0);
- X}
- X
- X
- X/********************************************************
- X* catch () *
- X* Catch SIGINT from lpd *
- X********************************************************/
- X
- Xvoid catch (signo)
- Xint signo;
- X{
- X fprintf (output_fp, "%c", CTLD_EOJ);
- X exit (0);
- X}
- X
- Xvoid output_trouble (rc)
- Xint rc;
- X{
- X#ifndef PSFFILTER
- X fprintf (stderr, "Cannot write to output file\n");
- X#endif
- X exit (rc);
- X}
- X/************************************************************************
- X* replacement_fonts() *
- X* get language-specific fonts and translation vectors. *
- X* Reads only the %%PsfStart -to- %%PsfEnd code. The file is is left *
- X* positioned at the first postscript code that prologue() will copy *
- X* to the output. *
- X************************************************************************/
- X
- Xvoid replacement_fonts ()
- X{ int found, i, fn, xold, xnew;
- X char line[201];
- X char *ln, *x, *fname;
- X
- X if (pdef == NULL)
- X return;
- X found = 0;
- X while (fgets (line, 200, pdef)) /* skip printer name */
- X { if (strncmp (line, "%%PsfStart", 10) == 0)
- X { found = 1;
- X break;
- X }
- X }
- X if (found)
- X { while (fgets (line, 200, pdef)) /* read fonts, translate */
- X { if (strncmp (line, "%%PsfEnd", 8) == 0)
- X break;
- X if (strncmp (line, "%%font", 6) == 0)
- X { fn = xtoi (line[6]) * 4;
- X if (fn >= font_count)
- X font_count = fn + 4;
- X trim (line);
- X ln = malloc (strlen (line) - 6);
- X strcpy (ln, line + 7);
- X fonts_have[fn] = 1;
- X fonts[fn++] = strtok (ln, " \t");
- X for (i = 1; i < 4; i++)
- X { fonts_have[fn] = 1;
- X fonts[fn++] = strtok (NULL, " \t");
- X }
- X }
- X else if (strncmp (line, "%%translate", 11) == 0)
- X { x = strtok (line + 11, " \t");
- X do
- X { xold = otoi (x) % 256;
- X xnew = otoi (x+4) % 256;
- X xlate[xold] = xnew;
- X } while (x = strtok (NULL, " \t"));
- X need_xlate = 1;
- X }
- X else if (strncmp (line, "%%copy", 6) == 0)
- X { fname = strtok (line + 6, " \t");
- X if (fname)
- X strcpy (copyfile, fname);
- X }
- X }
- X }
- X else
- X { fclose (pdef);
- X pdef = NULL;
- X }
- X return;
- X}
- X
- X/****************************************************************************
- X* octal to integer *
- X****************************************************************************/
- Xint otoi (s)
- Xchar *s;
- X{
- X int v, p, quit;
- X
- X v = 0;
- X while (*s == ' ')
- X s++;
- X quit = 0;
- X while (*s)
- X { switch (*s)
- X {
- X case '0': p = 0; break;
- X case '1': p = 1; break;
- X case '2': p = 2; break;
- X case '3': p = 3; break;
- X case '4': p = 4; break;
- X case '5': p = 5; break;
- X case '6': p = 6; break;
- X case '7': p = 7; break;
- X default: quit = 1;
- X }
- X if (quit)
- X break;
- X v = (v << 3) + p;
- X s++;
- X }
- X return (v);
- X}
- X
- X/****************************************************************************
- X* usage () *
- X****************************************************************************/
- X
- X#ifdef PSFFILTER
- X
- Xvoid usage ()
- X{ exit (1);
- X}
- Xvoid size_display ()
- X{ exit (1);
- X}
- X
- X#else /* not PSFFILTER */
- X
- Xstatic char *usage_text[] =
- X{
- X "Usage: %s [-1|2|4] [-b n] [-c n] [-d] [-f n] [-g type ] [-h]\n",
- X " [-H text] [-i n] [-l n] [-m n] [-n] [-p n] [-R n]",
- X " [-r n] [-s] [-t n] [-u fil] [-w] [-x] file ...",
- X "where:",
- X " -1|2|4 print 1,2,4 up (default=1)",
- X " -b n paper bin n",
- X " -c n print columns",
- X " -d double sided",
- X " -f n font number (def=0:Courier)",
- X " -g type letter legal a4 b5",
- X " -h file name header",
- X " -H text text header",
- X " -i n indent left margin points",
- X " -l n print lines per page",
- X " -L n lines per page",
- X " -m n top margin points",
- X " -n portrait (narrow) format",
- X " -p n point size n",
- X " -R n remove lines from beginning",
- X " -r n remove lines between pages",
- X " -s show page stats",
- X " -t n tabs to n (default=8)",
- X " -u fil use this file as psfprint.def",
- X " -v reverse page order",
- X " -w landscape (wide) format",
- X " -x draw cross (2/4-up page)",
- X " file.. name of files (or stdin)",
- X " output: stdout",
- X ""
- X} ;
- X
- X#define TOPCOUNT 4
- X
- Xvoid usage ()
- X{ int i, many, n, ff;
- X
- X fprintf (stderr, usage_text[0], pgmname);
- X for (i = 1; i < TOPCOUNT; i++)
- X fprintf (stderr, "%s\n", usage_text[i]);
- X
- X many = sizeof (usage_text)/sizeof (char *) - TOPCOUNT;
- X
- X for (i = 0; i < many/2; i++)
- X fprintf (stderr, "%-38s %-38s\n", usage_text[i+TOPCOUNT], usage_text[i+many/2+TOPCOUNT]);
- X
- X fprintf (stderr,"Fonts selection with -f n (number or name)\n");
- X many = ff = 0;
- X for (i = 0; i < font_count/4; i++)
- X { if (fonts_have[i*4])
- X { fprintf (stderr, " %c %-22s", ascii_hex[i], fonts[i*4]);
- X many++;
- X if ((ff = many % 3) == 0)
- X fprintf (stderr, "\n");
- X }
- X }
- X if (ff)
- X fprintf (stderr, "\n");
- X
- X fprintf (stderr, "Paper type/size selection with -g type\n");
- X many = 0;
- X for (i = 0; page_types[i].paper_name[0] != '\0'; i++)
- X { n = strlen (page_types[i].paper_name);
- X if (many + n > 75)
- X { many = 0;
- X fprintf (stderr,"\n");
- X ff = 0;
- X }
- X else ff = 1;
- X many += n + 3;
- X fprintf (stderr," %s", page_types[i].paper_name);
- X }
- X if (ff)
- X fprintf (stderr, "\n");
- X exit (1);
- X}
- X
- X/************************************************************************
- X* size_display () *
- X* print a table of point size, page size, line count, column count *
- X************************************************************************/
- X
- Xvoid size_display ()
- X{
- X int point_size, ps, nominal_high, nominal_wide, i;
- X int n_chars, n_lines;
- X double char_width;
- X char *which;
- X
- X fprintf (stderr, "%22s", "point size: ");
- X for (point_size = 6; point_size < 17; point_size += 2)
- X fprintf (stderr, " %5d ", point_size);
- X fprintf (stderr, "\n%-22s", " ");
- X for (point_size = 6; point_size < 17; point_size += 2)
- X fprintf (stderr, " lin col");
- X fprintf (stderr, "\n%-22s", "---- Page Layout ----");
- X for (point_size = 6; point_size < 17; point_size += 2)
- X fprintf (stderr, " --- ---");
- X fprintf (stderr, "\n");
- X for (ps = 0; page_types[ps].paper_name[0]; ps++)
- X { for (i = 0; i < 2; i++)
- X { if (i == 0)
- X { nominal_high = page_types[ps].y_size;
- X nominal_wide = page_types[ps].x_size;
- X which = "portrait";
- X }
- X else
- X { nominal_high = page_types[ps].x_size;
- X nominal_wide = page_types[ps].y_size;
- X which = "landscape";
- X }
- X fprintf (stderr, "%10.10s %9s: ", page_types[ps].paper_name, which);
- X for (point_size = 6; point_size < 17; point_size += 2)
- X { char_width = point_size / 12.0 * NOMINAL_CWIDE;
- X n_chars = ceil ((double) nominal_wide / (double) char_width);
- X n_lines = (double) nominal_high / (double) point_size;
- X fprintf (stderr, " %4d%4d", n_lines, n_chars);
- X }
- X fprintf (stderr, "\n");
- X }
- X }
- X exit (1);
- X}
- X#endif /* PSFFILTER */
- END_OF_FILE
- if test 52453 -ne `wc -c <'psf.c'`; then
- echo shar: \"'psf.c'\" unpacked with wrong size!
- fi
- # end of 'psf.c'
- fi
- echo shar: End of archive 9 \(of 9\).
- cp /dev/null ark9isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
- exit 0 # Just in case...
-